/**
 */
package fUML.Semantics.Loci.LociL1;

import fUML.Semantics.Classes.Kernel.Evaluation;

import fUML.Semantics.CommonBehaviors.BasicBehaviors.Execution;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.OpaqueBehaviorExecution;

import fUML.Syntax.Classes.Kernel.Element;
import fUML.Syntax.Classes.Kernel.PrimitiveType;
import fUML.Syntax.Classes.Kernel.ValueSpecification;

import fUML.Syntax.CommonBehaviors.BasicBehaviors.Behavior;
import fUML.Syntax.CommonBehaviors.BasicBehaviors.OpaqueBehavior;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EObject;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Execution Factory</b></em>'.
 * <!-- end-user-doc -->
 *
 * <!-- begin-model-doc -->
 *  An execution factory is used to create objects that represent the execution of
 *                 a behavior, the evaluation of a value specification or the activation of an activity
 *                 node.
 *  An execution factory is used to create objects that represent the execution of
 *                 a behavior, the evaluation of a value specification or the activation of an activity
 *                 node. This class only handles elements available at Conformance Level 2.
 *  An execution factory is used to create objects that represent the execution of
 *                 a behavior, the evaluation of a value specification or the activation of an activity
 *                 node. This class only handles elements available at Conformance Level 1.
 *  An execution factory is used to create objects that represent the execution of
 *                 a behavior, the evaluation of a value specification or the activation of an activity
 *                 node. This class only handles elements available at Conformance Level 3.
 * <!-- end-model-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.Loci.LociL1.ExecutionFactory#getLocus <em>Locus</em>}</li>
 *   <li>{@link fUML.Semantics.Loci.LociL1.ExecutionFactory#getPrimitiveBehaviorPrototypes <em>Primitive Behavior Prototypes</em>}</li>
 *   <li>{@link fUML.Semantics.Loci.LociL1.ExecutionFactory#getBuiltInTypes <em>Built In Types</em>}</li>
 *   <li>{@link fUML.Semantics.Loci.LociL1.ExecutionFactory#getStrategies <em>Strategies</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.Loci.LociL1.LociL1Package#getExecutionFactory()
 * @model abstract="true"
 * @generated
 */
public interface ExecutionFactory extends EObject {
	/**
	 * Returns the value of the '<em><b>Locus</b></em>' container reference.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Loci.LociL1.Locus#getFactory <em>Factory</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The locus at which this factory resides.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Locus</em>' container reference.
	 * @see #setLocus(Locus)
	 * @see fUML.Semantics.Loci.LociL1.LociL1Package#getExecutionFactory_Locus()
	 * @see fUML.Semantics.Loci.LociL1.Locus#getFactory
	 * @model opposite="factory" transient="false" ordered="false"
	 * @generated
	 */
	Locus getLocus();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Loci.LociL1.ExecutionFactory#getLocus <em>Locus</em>}' container reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Locus</em>' container reference.
	 * @see #getLocus()
	 * @generated
	 */
	void setLocus(Locus value);

	/**
	 * Returns the value of the '<em><b>Primitive Behavior Prototypes</b></em>' reference list.
	 * The list contents are of type {@link fUML.Semantics.CommonBehaviors.BasicBehaviors.OpaqueBehaviorExecution}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of opaque behavior executions to be used to execute the primitive
	 *                   behaviors known to the factory.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Primitive Behavior Prototypes</em>' reference list.
	 * @see fUML.Semantics.Loci.LociL1.LociL1Package#getExecutionFactory_PrimitiveBehaviorPrototypes()
	 * @model ordered="false"
	 * @generated
	 */
	EList<OpaqueBehaviorExecution> getPrimitiveBehaviorPrototypes();

	/**
	 * Returns the value of the '<em><b>Built In Types</b></em>' reference list.
	 * The list contents are of type {@link fUML.Syntax.Classes.Kernel.PrimitiveType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of primitive types that have corresponding literal value
	 *                   specifications.
	 *  Must include Integer, Boolean, String and
	 *                   UnlimitedNatural.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Built In Types</em>' reference list.
	 * @see fUML.Semantics.Loci.LociL1.LociL1Package#getExecutionFactory_BuiltInTypes()
	 * @model ordered="false"
	 * @generated
	 */
	EList<PrimitiveType> getBuiltInTypes();

	/**
	 * Returns the value of the '<em><b>Strategies</b></em>' reference list.
	 * The list contents are of type {@link fUML.Semantics.Loci.LociL1.SemanticStrategy}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of semantic strategies currently registered with this execution
	 *                   factory.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Strategies</em>' reference list.
	 * @see fUML.Semantics.Loci.LociL1.LociL1Package#getExecutionFactory_Strategies()
	 * @model ordered="false"
	 * @generated
	 */
	EList<SemanticStrategy> getStrategies();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create an execution object for a given behavior. 
	 *  // The execution
	 *                   will take place at the locus of the factory in the given context.
	 *  // If
	 *                   the context is empty, the execution is assumed to provide its own
	 *                   context.
	 *  
	 *  Execution execution;
	 *  
	 *  if (behavior
	 *                   instanceof OpaqueBehavior) {
	 *  execution =
	 *                   this.instantiateOpaqueBehaviorExecution((OpaqueBehavior)behavior);
	 *                   }
	 *  else {
	 *  execution =
	 *                   (Execution)this.instantiateVisitor(behavior);
	 *                   execution.types.addValue(behavior);
	 *                   execution.createFeatureValues();
	 *  }
	 *  
	 *                   this.locus.add(execution);
	 *  
	 *  if (context == null) {
	 *                   execution.context = execution;
	 *  }
	 *  else {
	 *                   execution.context = context;
	 *  }
	 *  
	 *  return
	 *                   execution;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" behaviorRequired="true" behaviorOrdered="false" contextOrdered="false"
	 * @generated
	 */
	Execution createExecution(Behavior behavior, fUML.Semantics.Classes.Kernel.Object context);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create an evaluation object for a given value specification. 
	 *  //
	 *                   The evaluation will take place at the locus of the factory.
	 *  
	 *                   Evaluation evaluation =
	 *                   (Evaluation)this.instantiateVisitor(specification);
	 *  
	 *                   evaluation.specification = specification;
	 *  evaluation.locus =
	 *                   this.locus;
	 *  
	 *  return evaluation;
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" specificationRequired="true" specificationOrdered="false"
	 * @generated
	 */
	Evaluation createEvaluation(ValueSpecification specification);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * Instantiate a visitor object for the given element.
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" elementRequired="true" elementOrdered="false"
	 * @generated
	 */
	SemanticVisitor instantiateVisitor(Element element);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Return a copy of the prototype for the primitive behavior execution of the
	 *                   given opaque behavior.
	 *  
	 *  OpaqueBehaviorExecution execution =
	 *                   null;
	 *  int i = 1;
	 *  while (execution == null & i <=
	 *                   this.primitiveBehaviorPrototypes.size()) {
	 *  //
	 *                   Debug.println("[instantiateOpaqueExecution] Checking " +
	 *                   this.primitiveBehaviorPrototypes.getValue(i).objectId() + "...");
	 *                   OpaqueBehaviorExecution prototype =
	 *                   this.primitiveBehaviorPrototypes.getValue(i-1);
	 *  if
	 *                   (prototype.getBehavior() == behavior) {
	 *  execution =
	 *                   (OpaqueBehaviorExecution)(prototype.copy());
	 *  }
	 *  i = i +
	 *                   1;
	 *  }
	 *  
	 *  if (execution == null) {
	 *                   Debug.println("[instantiateOpaqueExecution] No prototype execution found for " +
	 *                   behavior.name + ".");
	 *  }
	 *  
	 *  return execution;
	 *                 
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" behaviorRequired="true" behaviorOrdered="false"
	 * @generated
	 */
	OpaqueBehaviorExecution instantiateOpaqueBehaviorExecution(OpaqueBehavior behavior);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Add an opaque behavior execution to use as a prototype for instantiating
	 *                   the corresponding primitive opaque behavior.
	 *  // Precondition: No
	 *                   primitive behavior prototype for the type of the given execution should already
	 *                   exist.
	 *  
	 *                   this.primitiveBehaviorPrototypes.addValue(execution);
	 *  
	 * <!-- end-model-doc -->
	 * @model executionRequired="true" executionOrdered="false"
	 * @generated
	 */
	void addPrimitiveBehaviorPrototype(OpaqueBehaviorExecution execution);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Add the given primitive type as a built-in type.
	 *  // Precondition:
	 *                   No built-in type with the same name should already exist.
	 *  
	 *                   this.builtInTypes.addValue(type);
	 *  
	 * <!-- end-model-doc -->
	 * @model typeRequired="true" typeOrdered="false"
	 * @generated
	 */
	void addBuiltInType(PrimitiveType type);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Return the built-in type with the given name.
	 *  
	 *                   PrimitiveType type = null;
	 *  int i = 1;
	 *  while (type == null
	 *                   & i <= this.builtInTypes.size()) {
	 *  PrimitiveType
	 *                   primitiveType = this.builtInTypes.getValue(i-1);
	 *  if
	 *                   (primitiveType.name.equals(name)) {
	 *  type = primitiveType;
	 *                   }
	 *  i = i + 1;
	 *  }
	 *  
	 *  return type;
	 *  
	 * <!-- end-model-doc -->
	 * @model ordered="false" nameRequired="true" nameOrdered="false"
	 * @generated
	 */
	PrimitiveType getBuiltInType(String name);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model strategyRequired="true" strategyOrdered="false"
	 * @generated
	 */
	void setStrategy(SemanticStrategy strategy);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model ordered="false" nameRequired="true" nameOrdered="false"
	 * @generated
	 */
	SemanticStrategy getStrategy(String name);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model required="true" ordered="false" nameRequired="true" nameOrdered="false"
	 * @generated
	 */
	int getStrategyIndex(String name);

} // ExecutionFactory
